<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Vue.js 简易计算器</title>
    <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        [v-cloak] {
            display: none;
        }

        body {
            text-align: center;
        }

        table {
            margin: 250px auto;
            width: 20%;
            border: 2px solid #000000;
        }

        table th {
            height: 70px;
            font-size: 20px;
            text-align: right;
            padding-right: 10px;
            border: 1px solid #000000;
        }

        table td {
            width: 5%;
            height: 50px;
            background-color: #eeeeee;
            cursor: pointer;
            border: 1px solid #000000;
        }
    </style>
</head>

<body>
    <div id="main" v-cloak>
        <table>
            <tr>
                <th colspan="4">{{result.value}}</th>
            </tr>
            <tr>
                <td v-on:click="inputValue('+')">+</td>
                <td v-on:click="inputValue('-')">-</td>
                <td v-on:click="inputValue('x')">x</td>
                <td v-on:click="inputValue('÷')">÷</td>
            </tr>
            <tr>
                <td v-on:click="inputValue('1')">1</td>
                <td v-on:click="inputValue('2')">2</td>
                <td v-on:click="inputValue('3')">3</td>
                <td v-on:click="clearValue()">C</td>
            </tr>
            <tr>
                <td v-on:click="inputValue('4')">4</td>
                <td v-on:click="inputValue('5')">5</td>
                <td v-on:click="inputValue('6')">6</td>
                <td v-on:click="squareValue()">x²</td>
            </tr>
            <tr>
                <td v-on:click="inputValue('7')">7</td>
                <td v-on:click="inputValue('8')">8</td>
                <td v-on:click="inputValue('9')">9</td>
                <td v-on:click="sqrtValue()">√</td>
            </tr>
            <tr>
                <td v-on:click="backValue()">←</td>
                <td v-on:click="inputValue('0')">0</td>
                <td v-on:click="inputValue('.')">.</td>
                <td v-on:click="calValue()">=</td>
            </tr>
        </table>
    </div>
    <script>
        var demo = new Vue({
            el: "#main",
            data: {
                result: {
                    value: '0'
                }
            },
            methods: {
                inputValue(content) {
                    // 如果是数字类型，说明是上个计算结果,就清空内容
                    // if(Object.prototype.toString.call(this.result.value)=="[object Number]"){
                    //     this.result.value='0';
                    // }
                    // 输入内容时，将输入框内容转为字符串类型
                    var str = '' + this.result.value;
                    var len = str.length;
                    var arr = ["+", "-", "x", "÷"];
                    // num为输入框内最后一串数字，反复的分合逆序都是有意义的
                    var num = ('' + parseFloat(str.split('').reverse().join(''))).split('').reverse().join('');
                    var nlen = num.length;
                    // 输入框内最后一串数字不为0时拼接字符串
                    if ((num != '0' && content != '.') || (content == '.' && num.indexOf('.') == -1)) {
                        // 若一开始输入内容为运算符,输入无效
                        //.charAt() 方法用于返回指定索引处的字符
                        //indexOf()返回指定字符在字符串中第一次出现处的索引，如果此字符串中没有这样的字符，则返回 -1
                        if (arr.indexOf(str.charAt(len - 1)) != -1 && arr.indexOf(content) != -1) {
                            return;
                        }
                        // 拼接输入内容
                        this.result.value += content;
                    }
                    else {
                        arr.push('%');
                        // 若num中已有小数点,输入内容为小数点,视为无效
                        if (content == '.') {
                            return;
                        }
                        else if (!(arr.indexOf(content) != -1)) {//判断输入框内最后一个字符不为运算符
                            //输入框内最后一串数字为0时,删除0拼接
                            this.result.value = str.substring(0, str.length - nlen) + content;
                        }
                    }
                },
                // 计算结果
                calValue() {
                    var str = this.result.value;
                    str = str.replace('x', '*').replace('÷', '/');
                    try {
                        //若用户输入内容不符合运算规则,不计算
                        //eval() 函数用来执行一个字符串表达式，并返回表达式的值。
                        this.result.value = eval(str);
                    }
                    catch (error) {
                        return;
                    }
                },
                //清空输入框内容
                clearValue() {
                    this.result.value = '0';
                },

                // 删除键,删除单个字符
                backValue() {
                    var str = this.result.value;
                    if (str.length == 1) {
                        this.result.value = "0";
                    } else {
                        this.result.value = str.slice(0, str.length - 1);
                    }
                },
                //平方计算
                squareValue() {
                    var str = this.result.value;
                    //eval(str)函数很强大，将字符串str当成有效的表达式来求值并返回计算结果
                    //Math.pow(x,y)可返回 x 的 y 次幂的值
                    this.result.value = Math.pow(eval(str), 2);
                },
                //开平方计算
                sqrtValue() {
                    var str = this.result.value;
                    //sqrt(x)返回数的平方根。
                    this.result.value = Math.sqrt(eval(str))
                }

            }
        })
    </script>
</body>

</html>